
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Django 模板语言 &#8212; Django 3.2.6.dev 文档</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../../genindex.html" />
    <link rel="search" title="搜索" href="../../search.html" />
    <link rel="next" title="内置模板标签和过滤器" href="builtins.html" />
    <link rel="prev" title="模板" href="index.html" />



 
<script src="../../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django 3.2.6.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="index.html" title="模板">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="builtins.html" title="内置模板标签和过滤器">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="ref-templates-language">
            
  <div class="section" id="s-the-django-template-language">
<span id="the-django-template-language"></span><h1>Django 模板语言<a class="headerlink" href="#the-django-template-language" title="永久链接至标题">¶</a></h1>
<p>本文档解释了 Django 模板系统的语言语法。如果你想从技术角度了解它的工作原理以及如何扩展它，请参见 <a class="reference internal" href="api.html"><span class="doc">Django 模板语言：对于 Python 开发者</span></a>。</p>
<p>Django 的模板语言是为了在强大和简单之间取得平衡而设计的。它的设计让习惯于使用 HTML 的人感觉很舒服。如果你接触过其他基于文本的模板语言，如 <a class="reference external" href="https://www.smarty.net/">Smarty</a> 或 <a class="reference external" href="https://palletsprojects.com/p/jinja/">Jinja2</a> ，你应该会对 Django 的模板感到很舒服。</p>
<div class="admonition-philosophy admonition">
<p class="first admonition-title">设计哲学</p>
<p>如果你有编程背景，或者你习惯于将编程代码直接混入 HTML 的语言，你要记住，Django 模板系统并不是简单的将 Python 嵌入到 HTML 中。这是设计上的：模板系统是为了表达表现形式，而不是程序逻辑。</p>
<p class="last">Django 模板系统提供了类似于一些编程结构的标签——布尔测试的 <a class="reference internal" href="builtins.html#std:templatetag-if"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">if</span></code></a> 标签，循环的 <a class="reference internal" href="builtins.html#std:templatetag-for"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">for</span></code></a> 标签等等。——但这些并不是简单地作为相应的 Python 代码来执行，模板系统不会执行任意的 Python 表达式。默认情况下只支持下面列出的标签、过滤器和语法（尽管你可以根据需要在模板语言中添加 <a class="reference internal" href="../../howto/custom-template-tags.html"><span class="doc">你自己的扩展</span></a>）。</p>
</div>
<div class="section" id="s-templates">
<span id="templates"></span><h2>模板<a class="headerlink" href="#templates" title="永久链接至标题">¶</a></h2>
<p>模板是一个文本文件。它可以生成任何基于文本的格式（HTML、XML、CSV 等）。</p>
<p>一个模板包含 <strong>变量</strong> 和 <strong>标签</strong>，前者在模板被执行时被替换为值，后者控制模板的逻辑。</p>
<p>下面是一个最小的模板，说明了一些基本的内容。每一个元素将在本文档的后面解释。</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">&quot;base_generic.html&quot;</span> <span class="cp">%}</span>

<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}{{</span> <span class="nv">section.title</span> <span class="cp">}}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>

<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">section.title</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>

<span class="cp">{%</span> <span class="k">for</span> <span class="nv">story</span> <span class="k">in</span> <span class="nv">story_list</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;</span><span class="cp">{{</span> <span class="nv">story.get_absolute_url</span> <span class="cp">}}</span><span class="s">&quot;</span><span class="p">&gt;</span>
    <span class="cp">{{</span> <span class="nv">story.headline</span><span class="o">|</span><span class="nf">upper</span> <span class="cp">}}</span>
  <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">story.tease</span><span class="o">|</span><span class="nf">truncatewords</span><span class="s2">:&quot;100&quot;</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
</div>
<div class="admonition-philosophy admonition">
<p class="first admonition-title">设计哲学</p>
<p class="last">为什么使用基于文本的模板而不是基于 XML 的模板（比如 Zope 的 TAL）？我们希望 Django 的模板语言不仅仅适用于 XML／HTML 模板。你可以将模板语言用于任何基于文本的格式，如电子邮件、JavaScript 和 CSV。</p>
</div>
</div>
<div class="section" id="s-variables">
<span id="s-template-variables"></span><span id="variables"></span><span id="template-variables"></span><h2>变量<a class="headerlink" href="#variables" title="永久链接至标题">¶</a></h2>
<p>Variables look like this: <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">variable</span> <span class="pre">}}</span></code>. When the template engine
encounters a variable, it evaluates that variable and replaces it with the
result. Variable names consist of any combination of alphanumeric characters
and the underscore (<code class="docutils literal notranslate"><span class="pre">&quot;_&quot;</span></code>) but may not start with an underscore, and may not
be a number. The dot (<code class="docutils literal notranslate"><span class="pre">&quot;.&quot;</span></code>) also appears in variable sections, although that
has a special meaning, as indicated below. Importantly, <em>you cannot have spaces
or punctuation characters in variable names.</em></p>
<p>使用点号（<code class="docutils literal notranslate"><span class="pre">.</span></code>）来访问一个变量的属性。</p>
<div class="admonition-behind-the-scenes admonition">
<p class="first admonition-title">幕后</p>
<p>从技术上讲，当模板系统遇到一个点时，它会按照以下顺序尝试进行查找：</p>
<ul class="simple">
<li>字典查找</li>
<li>属性或方法查找</li>
<li>数字索引查找</li>
</ul>
<p>如果产生的值是可调用对象，则调用时不含参数。调用的结果成为模板值。</p>
<p>这种查找顺序可能会对覆盖字典查找的对象造成一些意外的行为。例如，考虑下面的代码片段，它试图在 <code class="docutils literal notranslate"><span class="pre">collections.defaultdict</span></code> 上循环：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">k</span><span class="o">,</span> <span class="nv">v</span> <span class="k">in</span> <span class="nv">defaultdict.items</span> <span class="cp">%}</span>
    Do something with k and v here...
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
</pre></div>
</div>
<p class="last">因为字典查找是先发生的，这种行为会启动并提供一个默认值，而不是使用预期的 <code class="docutils literal notranslate"><span class="pre">.items()</span></code> 方法。在这种情况下，可以考虑先转换为字典。</p>
</div>
<p>在上面的例子中，<code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">section.title</span> <span class="pre">}}</span></code> 将被 <code class="docutils literal notranslate"><span class="pre">section</span></code> 对象的 <code class="docutils literal notranslate"><span class="pre">title</span></code> 属性所取代。</p>
<p>如果你使用一个不存在的变量，模板系统会插入 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 选项的值，默认设置为 <code class="docutils literal notranslate"><span class="pre">''</span></code> （空字符串）。</p>
<p>请注意，像 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">foo.bar</span> <span class="pre">}}</span></code> 这样的模板表达式中的“bar”将被解释为一个字面字符串，而不是使用变量“bar”的值，如果模板上下文中存在的话。</p>
<p>以下划线开头的变量属性可能不会被访问，因为它们通常被认为是私有的。</p>
</div>
<div class="section" id="s-filters">
<span id="filters"></span><h2>过滤器<a class="headerlink" href="#filters" title="永久链接至标题">¶</a></h2>
<p>你可以通过使用 <strong>过滤器</strong> 修改显示的变量。</p>
<p>过滤器是这样的： <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">name|lower</span> <span class="pre">}}</span></code>。这将显示 <a class="reference internal" href="builtins.html#std:templatefilter-lower"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">lower</span></code></a> 过滤器过滤后的 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">name</span> <span class="pre">}}</span></code> 变量的值，该过滤器将文本转换为小写。使用管道（<code class="docutils literal notranslate"><span class="pre">|</span></code>）来应用过滤器。</p>
<p>过滤器可以“链式的”。一个过滤器的输出被应用到下一个过滤器。<code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">text|escape|linebreaks</span> <span class="pre">}}</span></code> 是一个常用的成语，用于转义文本内容，然后将换行符转换为 <code class="docutils literal notranslate"><span class="pre">&lt;p&gt;</span></code> 标签。</p>
<p>有些过滤器需要参数。一个过滤器的参数是这样的： <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">bio|truncatewords:30</span> <span class="pre">}}</span></code>。这将显示 <code class="docutils literal notranslate"><span class="pre">bio</span></code> 变量的前 30 个字。</p>
<p>包含空格的过滤器参数必须加引号；例如，要连接一个包含逗号和空格的列表，你可以使用 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">list|join:&quot;,</span> <span class="pre">&quot;</span> <span class="pre">}}</span></code>。</p>
<p>Django 提供了大约 60 个内置的模板过滤器。你可以在 <a class="reference internal" href="builtins.html#ref-templates-builtins-filters"><span class="std std-ref">内置过滤器参考</span></a> 中阅读它们。为了让你了解这些模板过滤器，这里有一些比较常用的模板过滤器：</p>
<dl class="docutils">
<dt><a class="reference internal" href="builtins.html#std:templatefilter-default"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">default</span></code></a></dt>
<dd><p class="first">如果一个变量为 false 或空，使用给定的默认值。否则，使用变量的值。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">value</span><span class="o">|</span><span class="nf">default</span><span class="s2">:&quot;nothing&quot;</span> <span class="cp">}}</span>
</pre></div>
</div>
<p class="last">如果 <code class="docutils literal notranslate"><span class="pre">value</span></code> 没有提供或者为空，那么他将显示为“<code class="docutils literal notranslate"><span class="pre">nothing</span></code>”。</p>
</dd>
<dt><a class="reference internal" href="builtins.html#std:templatefilter-length"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">length</span></code></a></dt>
<dd><p class="first">返回值的长度。这对字符串和列表都有效。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">value</span><span class="o">|</span><span class="nf">length</span> <span class="cp">}}</span>
</pre></div>
</div>
<p class="last">如果 <code class="docutils literal notranslate"><span class="pre">value</span></code> 为 <code class="docutils literal notranslate"><span class="pre">['a',</span> <span class="pre">'b',</span> <span class="pre">'c',</span> <span class="pre">'d']</span></code>, 那么他将被显示为 <code class="docutils literal notranslate"><span class="pre">4</span></code>。</p>
</dd>
<dt><a class="reference internal" href="builtins.html#std:templatefilter-filesizeformat"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">filesizeformat</span></code></a></dt>
<dd><p class="first">以“人类可读”的文件大小格式化该值（即 <code class="docutils literal notranslate"><span class="pre">'13</span> <span class="pre">KB'</span></code>、<code class="docutils literal notranslate"><span class="pre">'4.1</span> <span class="pre">MB'</span></code>、<code class="docutils literal notranslate"><span class="pre">'102</span> <span class="pre">bytes'</span></code> 等)。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">value</span><span class="o">|</span><span class="nf">filesizeformat</span> <span class="cp">}}</span>
</pre></div>
</div>
<p class="last">如果 <code class="docutils literal notranslate"><span class="pre">value</span></code> 是 123456789，则输出为 <code class="docutils literal notranslate"><span class="pre">117.7</span> <span class="pre">MB</span></code>。</p>
</dd>
</dl>
<p>这些只是几个例子，请参阅  <a class="reference internal" href="builtins.html#ref-templates-builtins-filters"><span class="std std-ref">内置过滤器参考</span></a> 的完整列表。</p>
<p>你还可以创建自己的自定义模板过滤器，请参见 <a class="reference internal" href="../../howto/custom-template-tags.html"><span class="doc">自定义模板标签和过滤器</span></a>。</p>
<div class="admonition seealso">
<p class="first admonition-title">参见</p>
<p class="last">Django 的管理界面可以包含一个完整的给定网站的所有模板标签和过滤器的参考。参见 <a class="reference internal" href="../contrib/admin/admindocs.html"><span class="doc">Django 管理文档生成器</span></a>。</p>
</div>
</div>
<div class="section" id="s-tags">
<span id="tags"></span><h2>标签<a class="headerlink" href="#tags" title="永久链接至标题">¶</a></h2>
<p>标签是这样的： <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">tag</span> <span class="pre">%}</span></code>。标签比变量更复杂。有的在输出中创建文本，有的通过执行循环或逻辑来控制流程，有的将外部信息加载到模板中，供以后的变量使用。</p>
<p>有些标签要求有开始和结束标签（即 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">tag</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">tag</span> <span class="pre">contents</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endtag</span> <span class="pre">%}</span></code>）。</p>
<p>Django 有二十多个内置的模板标签。你可以在 <a class="reference internal" href="builtins.html#ref-templates-builtins-tags"><span class="std std-ref">内置标签参考</span></a> 中阅读所有关于它们的信息。为了让你了解这些标签，这里有一些比较常用的标签。</p>
<dl class="docutils">
<dt><a class="reference internal" href="builtins.html#std:templatetag-for"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">for</span></code></a></dt>
<dd><p class="first">循环浏览数组中的每个项目。 例如，要显示 <code class="docutils literal notranslate"><span class="pre">athlete_list</span></code> 中提供的运动员名单：</p>
<div class="last highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">athlete</span> <span class="k">in</span> <span class="nv">athlete_list</span> <span class="cp">%}</span>
    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">athlete.name</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</pre></div>
</div>
</dd>
<dt><a class="reference internal" href="builtins.html#std:templatetag-if"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">if</span></code></a>、<code class="docutils literal notranslate"><span class="pre">elif</span></code> 和 <code class="docutils literal notranslate"><span class="pre">else</span></code></dt>
<dd><p class="first">判断一个变量的布尔值，如果该是“true”，则显示块的内容：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">athlete_list</span> <span class="cp">%}</span>
    Number of athletes: <span class="cp">{{</span> <span class="nv">athlete_list</span><span class="o">|</span><span class="nf">length</span> <span class="cp">}}</span>
<span class="cp">{%</span> <span class="k">elif</span> <span class="nv">athlete_in_locker_room_list</span> <span class="cp">%}</span>
    Athletes should be out of the locker room soon!
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span>
    No athletes.
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span>
</pre></div>
</div>
<p>在上述情况下，如果 <code class="docutils literal notranslate"><span class="pre">athlete_list</span></code> 不为空，则会通过 <code class="docutils literal notranslate"><span class="pre">{</span> <span class="pre">athlete_list|length</span> <span class="pre">}}</span></code> 变量显示运动员的数量。否则，如果 <code class="docutils literal notranslate"><span class="pre">athlete_in_locker_room_list</span></code> 不为空，则会显示“Athletes should be out...”的消息。如果两个列表都是空的，将显示“No athletes.”。</p>
<p>你也可以在 <a class="reference internal" href="builtins.html#std:templatetag-if"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">if</span></code></a> 标签中使用过滤器和各种操作符：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">athlete_list</span><span class="o">|</span><span class="nf">length</span> <span class="o">&gt;</span> <span class="m">1</span> <span class="cp">%}</span>
   Team: <span class="cp">{%</span> <span class="k">for</span> <span class="nv">athlete</span> <span class="k">in</span> <span class="nv">athlete_list</span> <span class="cp">%}</span> ... <span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span>
   Athlete: <span class="cp">{{</span> <span class="nv">athlete_list.0.name</span> <span class="cp">}}</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span>
</pre></div>
</div>
<p class="last">虽然上面的例子是可行的，但要注意大多数模板过滤器都会返回字符串，所以使用过滤器进行数学比较一般不会像你预期的那样。</p>
</dd>
<dt><a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 和 <a class="reference internal" href="builtins.html#std:templatetag-extends"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">extends</span></code></a></dt>
<dd>设置 <a class="reference internal" href="#id1">模板继承</a> （见下文），这是减少模板中 “样板代码” 的有力方法。</dd>
</dl>
<p>同样，以上只是整个列表的一部分，完整的列表请参见 <a class="reference internal" href="builtins.html#ref-templates-builtins-tags"><span class="std std-ref">内置标签参考</span></a>。</p>
<p>你也可以创建你自己的模板标签；参见 <a class="reference internal" href="../../howto/custom-template-tags.html"><span class="doc">自定义模板标签和过滤器</span></a>。</p>
<div class="admonition seealso">
<p class="first admonition-title">参见</p>
<p class="last">Django 的管理界面可以包含一个完整的给定网站的所有模板标签和过滤器的参考。参见 <a class="reference internal" href="../contrib/admin/admindocs.html"><span class="doc">Django 管理文档生成器</span></a>。</p>
</div>
</div>
<div class="section" id="s-comments">
<span id="s-template-comments"></span><span id="comments"></span><span id="template-comments"></span><h2>注释<a class="headerlink" href="#comments" title="永久链接至标题">¶</a></h2>
<p>要对模板中的部分行进行注释，请使用注释语法。<code class="docutils literal notranslate"><span class="pre">{#</span> <span class="pre">#}</span></code>。</p>
<p>例如，这个模板将呈现为 <code class="docutils literal notranslate"><span class="pre">'hello'</span></code>:</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="c">{# greeting #}</span>hello
</pre></div>
</div>
<p>注释可以包含任何模板代码，无论有效或无效。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="c">{# {% if foo %}bar{% else %} #}</span>
</pre></div>
</div>
<p>这种语法只能用于单行注释（在 <code class="docutils literal notranslate"><span class="pre">{#</span></code> 和 <code class="docutils literal notranslate"><span class="pre">#}</span></code> 定界符之间不允许使用换行）。如果你需要对模板的多行部分进行注释，请参见 <a class="reference internal" href="builtins.html#std:templatetag-comment"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">comment</span></code></a> 标签。</p>
</div>
<div class="section" id="s-template-inheritance">
<span id="s-id1"></span><span id="template-inheritance"></span><span id="id1"></span><h2>模板继承<a class="headerlink" href="#template-inheritance" title="永久链接至标题">¶</a></h2>
<p>Django 的模板引擎中最强大的——也是最复杂的——部分是模板继承。模板继承允许你建立一个基本的“骨架”模板，它包含了你网站的所有常用元素，并定义了子模板可以覆盖的 <strong>块</strong>。</p>
<p>我们先看一个例子，看看模板继承：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&quot;en&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;style.css&quot;</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}</span>My amazing site<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;sidebar&quot;</span><span class="p">&gt;</span>
        <span class="cp">{%</span> <span class="k">block</span> <span class="nv">sidebar</span> <span class="cp">%}</span>
        <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/&quot;</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/blog/&quot;</span><span class="p">&gt;</span>Blog<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
        <span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>

    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;content&quot;</span><span class="p">&gt;</span>
        <span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>这个模板，我们称之为 <code class="docutils literal notranslate"><span class="pre">base.html</span></code>，它定义了一个 HTML 骨架文档，你可以用它来制作一个两栏式页面。“子”模板的工作是用内容填充空块。</p>
<p>在这个例子中，<a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 标签定义了三个块，子模板可以填入其中。<a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 标签所做的就是告诉模板引擎，子模板可以覆盖模板的这些部分。</p>
<p>一个子模板可能是这样的：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">&quot;base.html&quot;</span> <span class="cp">%}</span>

<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}</span>My amazing blog<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>

<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">entry</span> <span class="k">in</span> <span class="nv">blog_entries</span> <span class="cp">%}</span>
    <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">entry.title</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">entry.body</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
</div>
<p><a class="reference internal" href="builtins.html#std:templatetag-extends"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">extends</span></code></a> 标签是这里的关键。它告诉模板引擎，这个模板“扩展”了另一个模板。当模板系统执行这个模板时，首先要找到父模板——在本例中是“base.html”。</p>
<p>这时，模板引擎会注意到 <code class="docutils literal notranslate"><span class="pre">base.html</span></code> 中的三个 <a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 标签，然后用子模板的内容替换这些块。根据 <code class="docutils literal notranslate"><span class="pre">blog_entries</span></code> 的值，输出可能是这样的：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&quot;en&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;style.css&quot;</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My amazing blog<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;sidebar&quot;</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/&quot;</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/blog/&quot;</span><span class="p">&gt;</span>Blog<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>

    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;content&quot;</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Entry one<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is my first entry.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

        <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Entry two<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is my second entry.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>请注意，由于子模板没有定义 <code class="docutils literal notranslate"><span class="pre">sidebar</span></code> 块，所以使用父模板的值来代替。父模板中 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></code> 标签中的内容总是被用作后备。</p>
<p>你可以根据需要使用任意层次的继承。一种常见的使用继承的方式是像以下的三层继承：</p>
<ul class="simple">
<li>创建一个 <code class="docutils literal notranslate"><span class="pre">base.html</span></code> 模板，以保持你网站的主要外观和风格。</li>
<li>为你网站的每个“部分”创建一个 <code class="docutils literal notranslate"><span class="pre">base_SECTIONNAME.html</span></code> 模板。例如，<code class="docutils literal notranslate"><span class="pre">base_news.html</span></code>、<code class="docutils literal notranslate"><span class="pre">base_sports.html</span></code>。这些模板都是对 <code class="docutils literal notranslate"><span class="pre">base.html</span></code> 的扩展，并包括特定部分的样式／设计。</li>
<li>为每种类型的页面创建单独的模板，如新闻文章或博客条目。这些模板扩展了相应的部分模板。</li>
</ul>
<p>这种方法可以最大限度地重用代码，并有助于将项目添加到共享内容区域，如全部分导航。</p>
<p>下面是一些关于继承工作的技巧：</p>
<ul>
<li><p class="first">如果你在模板中使用 <a class="reference internal" href="builtins.html#std:templatetag-extends"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></code></a>，它必须是该模板中的第一个模板标签。否则，模板继承将无法使用。</p>
</li>
<li><p class="first">基础模板中的 <a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></code></a> 标签越多越好。记住，子模板不需要定义所有的父块，所以你可以在一些块中填入合理的默认值，然后只定义以后需要的块。钩子多比钩子少好。</p>
</li>
<li><p class="first">如果你发现自己的内容在多个模板中重复，可能意味着你应该把这些内容移到父模板中的 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></code>。</p>
</li>
<li><p class="first">如果你需要从父模板中获取块的内容，<code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">block.super</span> <span class="pre">}}</span></code> 变量就可以做到这一点。如果你想添加到父模板的内容中，而不是完全覆盖它，这很有用。使用 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">block.super</span> <span class="pre">}}</span></code> 插入的数据不会被自动转义（参见 <a class="reference external" href="#automatic-html-escaping">下一节</a> ），因为如果需要的话，它已经在父模板中被转义了。</p>
</li>
<li><p class="first">通过使用与继承模板相同的模板名称，<a class="reference internal" href="builtins.html#std:templatetag-extends"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></code></a> 可以在覆盖模板的同时继承它。结合 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">block.super</span> <span class="pre">}}</span></code>，这可以成为一种强大的小规模定制方式。完整的例子请参见 <a class="reference internal" href="../../howto/overriding-templates.html#extending-an-overridden-template"><span class="std std-ref">扩展复写模板</span></a> 中的 <em>Overriding templates</em> How-to。</p>
</li>
<li><p class="first">在 <a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></code></a> 之外使用模板标签 <code class="docutils literal notranslate"><span class="pre">as</span></code> 语法创建的变量不能在块中使用。例如，这个模板不会呈现任何东西：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">translate</span> <span class="s2">&quot;Title&quot;</span> <span class="k">as</span> <span class="nv">title</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}{{</span> <span class="nv">title</span> <span class="cp">}}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
</div>
</li>
<li><p class="first">为了增加可读性，你可以给你的 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">endblock</span> <span class="pre">%}</span></code> 标签 <em>起一个</em> 名字。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span>
...
<span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">content</span> <span class="cp">%}</span>
</pre></div>
</div>
<p>在较大的模板中，这种技术可以帮助你看到哪些 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></code> 标签正在被关闭。</p>
</li>
</ul>
<p>最后，请注意，你不能在同一个模板中定义多个同名的 <a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 标签。之所以有这种限制，是因为块标签可以“双向”工作。也就是说，一个块标签不只是提供一个洞来填补——它还定义了填补 <em>父</em> 模板中洞的内容。如果一个模板中有两个名称相似的 <a class="reference internal" href="builtins.html#std:templatetag-block"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">block</span></code></a> 标签，那么该模板的父标签就不知道该使用哪一个块的内容。</p>
</div>
<div class="section" id="s-automatic-html-escaping">
<span id="s-id2"></span><span id="automatic-html-escaping"></span><span id="id2"></span><h2>自动 HTML 转义<a class="headerlink" href="#automatic-html-escaping" title="永久链接至标题">¶</a></h2>
<p>当从模板中生成 HTML 时，总是存在一个风险，即变量会包含影响生成的 HTML 的字符。例如，考虑这个模板片段：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>Hello, <span class="cp">{{</span> <span class="nv">name</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>乍一看，这似乎是一种无伤大雅的显示用户姓名的方式，但考虑一下，如果用户将自己的姓名输入为：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span><span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">)&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>有了这个名称值，模板将呈现为：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>Hello, <span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span><span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">)&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>...这意味着浏览器会弹出一个 JavaScript 提示框！</p>
<p>同样，如果名称中包含一个 <code class="docutils literal notranslate"><span class="pre">'&lt;'</span></code> 符号，像这样呢？</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">b</span><span class="p">&gt;</span>username
</pre></div>
</div>
<p>这样一来，呈现出来的模板就会是这样的：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>Hello, <span class="p">&lt;</span><span class="nt">b</span><span class="p">&gt;</span>username
</pre></div>
</div>
<p>...这又会导致网页的其余部分被加粗！</p>
<p>显然，不应该盲目相信用户提交的数据，直接插入到你的网页中，因为恶意用户可能会利用这种漏洞做潜在的坏事。这种类型的安全漏洞被称为 <a class="reference external" href="https://en.wikipedia.org/wiki/Cross-site_scripting">跨站点脚本</a> （XSS）攻击。</p>
<p>为了避免这个问题，你有两个选择：</p>
<ul class="simple">
<li>一，你可以确保通过 <a class="reference internal" href="builtins.html#std:templatefilter-escape"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">escape</span></code></a> 过滤器来运行每个不受信任的变量（如下文所述），它可以将潜在的有害 HTML 字符转换为无害的字符。在 Django 的前几年，这是默认的解决方案，但问题是它把责任推给了 <em>你</em>，开发者／模板作者，以确保你的一切都被转义。很容易忘记对数据进行转义。</li>
<li>二，你可以利用 Django 的自动 HTML 转义功能。本节剩余部分将介绍自动转义的工作原理。</li>
</ul>
<p>在 Django 中，默认情况下，每个模板都会自动转义每个变量标签的输出。具体来说，这五个字符会被转义：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">&lt;</span></code> 被替换为 <code class="docutils literal notranslate"><span class="pre">&amp;lt;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">&gt;</span></code> 被替换为 <code class="docutils literal notranslate"><span class="pre">&amp;gt;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'</span></code> （单引号）被替换为 <code class="docutils literal notranslate"><span class="pre">&amp;#x27;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;</span></code> （双引号）被替换为 <code class="docutils literal notranslate"><span class="pre">&amp;quot;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">&amp;</span></code> 被替换为 <code class="docutils literal notranslate"><span class="pre">&amp;amp;</span></code></li>
</ul>
<p>我们再次强调，这个行为是默认开启的。如果你使用的是 Django 的模板系统，你就会受到保护。</p>
<div class="section" id="s-how-to-turn-it-off">
<span id="how-to-turn-it-off"></span><h3>如何关闭它<a class="headerlink" href="#how-to-turn-it-off" title="永久链接至标题">¶</a></h3>
<p>如果你不希望数据被自动转义, 你可以在站点、模板,、变量这三个层面关闭它：</p>
<p>为什么要关闭它？因为有时，模板变量包含的数据是你希望以原始 HTML 的形式呈现的，在这种情况下，你不希望其内容被转义。例如，你可能在数据库中存储了一个 HTML 片段，并希望将其直接嵌入到模板中。或者，你可能会使用 Django 的模板系统来生成非 HTML 的文本——比如说，电子邮件。</p>
<div class="section" id="s-for-individual-variables">
<span id="for-individual-variables"></span><h4>对于单个变量<a class="headerlink" href="#for-individual-variables" title="永久链接至标题">¶</a></h4>
<p>要禁用单个变量的自动转义，请使用 <a class="reference internal" href="builtins.html#std:templatefilter-safe"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">safe</span></code></a> 过滤器：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>This will be escaped: <span class="cp">{{</span> <span class="nv">data</span> <span class="cp">}}</span>
This will not be escaped: <span class="cp">{{</span> <span class="nv">data</span><span class="o">|</span><span class="nf">safe</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>把 <em>safe</em> 看作是 <em>safe from further escaping</em> 或 <em>can be safely interpreted as HTML</em> 的简写。在这个例子中，如果 <code class="docutils literal notranslate"><span class="pre">data</span></code> 包含 <code class="docutils literal notranslate"><span class="pre">'&lt;b&gt;'</span></code>，输出将是：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>This will be escaped: <span class="ni">&amp;lt;</span>b<span class="ni">&amp;gt;</span>
This will not be escaped: <span class="p">&lt;</span><span class="nt">b</span><span class="p">&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="s-for-template-blocks">
<span id="for-template-blocks"></span><h4>对于模板块<a class="headerlink" href="#for-template-blocks" title="永久链接至标题">¶</a></h4>
<p>要控制模板的自动转义，可以用 <code class="xref std std-ttag docutils literal notranslate"><span class="pre">autescape</span></code> 标签来包装模板（或模板的某一特定部分），就像这样：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">autoescape</span> <span class="nv">off</span> <span class="cp">%}</span>
    Hello <span class="cp">{{</span> <span class="nv">name</span> <span class="cp">}}</span>
<span class="cp">{%</span> <span class="k">endautoescape</span> <span class="cp">%}</span>
</pre></div>
</div>
<p><a class="reference internal" href="builtins.html#std:templatetag-autoescape"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">autoescape</span></code></a> 标签使用 <code class="docutils literal notranslate"><span class="pre">on</span></code> 或 <code class="docutils literal notranslate"><span class="pre">off</span></code> 作为参数。有时，你可能会想在不使用自动转义的情况下强制使用。以下是一个模板示例：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span>Auto-escaping is on by default. Hello <span class="cp">{{</span> <span class="nv">name</span> <span class="cp">}}</span>

<span class="cp">{%</span> <span class="k">autoescape</span> <span class="nv">off</span> <span class="cp">%}</span>
    This will not be auto-escaped: <span class="cp">{{</span> <span class="nv">data</span> <span class="cp">}}</span>.

    Nor this: <span class="cp">{{</span> <span class="nv">other_data</span> <span class="cp">}}</span>
    <span class="cp">{%</span> <span class="k">autoescape</span> <span class="nv">on</span> <span class="cp">%}</span>
        Auto-escaping applies again: <span class="cp">{{</span> <span class="nv">name</span> <span class="cp">}}</span>
    <span class="cp">{%</span> <span class="k">endautoescape</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endautoescape</span> <span class="cp">%}</span>
</pre></div>
</div>
<p>自动转义标签将其效果传递给扩展当前模板的模板以及通过 <a class="reference internal" href="builtins.html#std:templatetag-include"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">include</span></code></a> 标签包含的模板，就像所有的块标签一样。例如：</p>
<div class="literal-block-wrapper docutils container" id="id4">
<div class="code-block-caption"><span class="caption-text">base.html</span><a class="headerlink" href="#id4" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">autoescape</span> <span class="nv">off</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endautoescape</span> <span class="cp">%}</span>
</pre></div>
</div>
</div>
<div class="literal-block-wrapper docutils container" id="id5">
<div class="code-block-caption"><span class="caption-text">child.html</span><a class="headerlink" href="#id5" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">&quot;base.html&quot;</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}</span>This <span class="ni">&amp;amp;</span> that<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}{{</span> <span class="nv">greeting</span> <span class="cp">}}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
</div>
</div>
<p>由于在基础模板中关闭了自动转义，所以在子模板中也会关闭，当 <code class="docutils literal notranslate"><span class="pre">greeting</span></code> 变量中包含字符串 <code class="docutils literal notranslate"><span class="pre">&lt;b&gt;Hello!&lt;/b&gt;</span></code> 时，会出现以下的 HTML 渲染结果：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>This <span class="ni">&amp;amp;</span> that<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">b</span><span class="p">&gt;</span>Hello!<span class="p">&lt;/</span><span class="nt">b</span><span class="p">&gt;</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="s-notes">
<span id="notes"></span><h3>注意<a class="headerlink" href="#notes" title="永久链接至标题">¶</a></h3>
<p>一般来说，模板作者不需要很担心自动转义的问题。Python 方面的开发人员（编写视图和自定义过滤器的人）需要考虑在哪些情况下数据不应该被转义，并适当地标记数据，所以事情在模板中 Just Work。</p>
<p>如果你创建的模板可能会在你不确定是否启用自动转义的情况下使用，那么在任何需要转义的变量中添加一个 <a class="reference internal" href="builtins.html#std:templatefilter-escape"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">escape</span></code></a> 过滤器。当自动转义开启时，不会出现 <a class="reference internal" href="builtins.html#std:templatefilter-escape"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">escape</span></code></a> 过滤器 <em>双重转义</em> 数据的危险 —— <a class="reference internal" href="builtins.html#std:templatefilter-escape"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">escape</span></code></a> 过滤器不会影响自动转义的变量。</p>
</div>
<div class="section" id="s-string-literals-and-automatic-escaping">
<span id="s-id3"></span><span id="string-literals-and-automatic-escaping"></span><span id="id3"></span><h3>字符串和自动转义<a class="headerlink" href="#string-literals-and-automatic-escaping" title="永久链接至标题">¶</a></h3>
<p>正如我们前面提到的，过滤器的参数可以是字符串：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">data</span><span class="o">|</span><span class="nf">default</span><span class="s2">:&quot;This is a string literal.&quot;</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>所有的字符串文字都是在 <strong>没有</strong> 任何自动转义的情况下插入到模板中的——就好像它们都通过了 <a class="reference internal" href="builtins.html#std:templatefilter-safe"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">safe</span></code></a> 过滤器一样。这背后的原因是，模板作者可以控制字符串文字的内容，因此他们可以确保在编写模板时正确地转义文本。</p>
<p>这意味着你应当这么写：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">data</span><span class="o">|</span><span class="nf">default</span><span class="s2">:&quot;3 &amp;lt; 2&quot;</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>...而不是：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">data</span><span class="o">|</span><span class="nf">default</span><span class="s2">:&quot;3 &lt; 2&quot;</span> <span class="cp">}}</span>  <span class="c">{# Bad! Don&#39;t do this. #}</span>
</pre></div>
</div>
<p>这并不影响来自变量本身的数据的处理。如果有必要，变量的内容仍然会被自动转义，因为它们超出了模板作者的控制范围。</p>
</div>
</div>
<div class="section" id="s-accessing-method-calls">
<span id="s-template-accessing-methods"></span><span id="accessing-method-calls"></span><span id="template-accessing-methods"></span><h2>访问方法调用<a class="headerlink" href="#accessing-method-calls" title="永久链接至标题">¶</a></h2>
<p>大多数附加到对象上的方法调用也可以从模板中获得。这意味着模板可以访问的东西远不止是类属性（如字段名）和从视图中传递过来的变量。例如，Django ORM 提供了 <a class="reference internal" href="../../topics/db/queries.html#topics-db-queries-related"><span class="std std-ref">&quot;entry_set&quot;</span></a> 语法，用于查找一个外键相关的对象集合。因此，给定一个名为“comment”的模型与一个名为“task”的模型的外键关系，你可以像这样循环浏览所有附加在给定任务上的评论：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">comment</span> <span class="k">in</span> <span class="nv">task.comment_set.all</span> <span class="cp">%}</span>
    <span class="cp">{{</span> <span class="nv">comment</span> <span class="cp">}}</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
</pre></div>
</div>
<p>同样，<a class="reference internal" href="../models/querysets.html"><span class="doc">QuerySets</span></a> 提供了一个 <code class="docutils literal notranslate"><span class="pre">count()</span></code> 方法来计算它们所包含的对象数量。因此，你可以通过以下方法获得与当前任务相关的所有注释的数量：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">task.comment_set.all.count</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>你也可以访问你在自己的模型上明确定义的方法：</p>
<div class="literal-block-wrapper docutils container" id="id6">
<div class="code-block-caption"><span class="caption-text">models.py</span><a class="headerlink" href="#id6" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Task</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;bar&quot;</span>
</pre></div>
</div>
</div>
<div class="literal-block-wrapper docutils container" id="id7">
<div class="code-block-caption"><span class="caption-text">template.html</span><a class="headerlink" href="#id7" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">task.foo</span> <span class="cp">}}</span>
</pre></div>
</div>
</div>
<p>由于 Django 有意限制了模板语言中可用的逻辑处理量，所以不可能将参数传递给从模板内访问的方法调用。数据应该在视图中计算，然后传递给模板显示。</p>
</div>
<div class="section" id="s-custom-tag-and-filter-libraries">
<span id="s-loading-custom-template-libraries"></span><span id="custom-tag-and-filter-libraries"></span><span id="loading-custom-template-libraries"></span><h2>自定义标签和过滤器库<a class="headerlink" href="#custom-tag-and-filter-libraries" title="永久链接至标题">¶</a></h2>
<p>某些应用程序提供了自定义标签和过滤器库。要在模板中访问它们，请确保应用程序在 <a class="reference internal" href="../settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a> 中（本例中我们会添加 <code class="docutils literal notranslate"><span class="pre">'django.contrib.humanize'</span></code>），然后在模板中使用 <a class="reference internal" href="builtins.html#std:templatetag-load"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">load</span></code></a> 标签：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">load</span> <span class="nv">humanize</span> <span class="cp">%}</span>

<span class="cp">{{</span> <span class="m">45000</span><span class="o">|</span><span class="nf">intcomma</span> <span class="cp">}}</span>
</pre></div>
</div>
<p>在上面的例子中， <a class="reference internal" href="builtins.html#std:templatetag-load"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">load</span></code></a> 标签加载了 <code class="docutils literal notranslate"><span class="pre">humanize</span></code> 标签库，然后使 <code class="docutils literal notranslate"><span class="pre">intcomma</span></code> 过滤器可以使用。如果你已经启用了 <a class="reference internal" href="../contrib/admin/admindocs.html#module-django.contrib.admindocs" title="django.contrib.admindocs: Django's admin documentation generator."><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.admindocs</span></code></a>，你可以在你的管理中的文档区查找安装中的自定义库列表。</p>
<p><a class="reference internal" href="builtins.html#std:templatetag-load"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">load</span></code></a> 标签可以使用多个库名，用空格分隔。例如：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">load</span> <span class="nv">humanize</span> <span class="nv">i18n</span> <span class="cp">%}</span>
</pre></div>
</div>
<p>参见 <a class="reference internal" href="../../howto/custom-template-tags.html"><span class="doc">自定义模板标签和过滤器</span></a> 了解如何编写自己的模板库。</p>
<div class="section" id="s-custom-libraries-and-template-inheritance">
<span id="custom-libraries-and-template-inheritance"></span><h3>自定义库和模板继承<a class="headerlink" href="#custom-libraries-and-template-inheritance" title="永久链接至标题">¶</a></h3>
<p>当你加载自定义标签或过滤器库时，标签／过滤器仅对当前模板可用，而不是沿模板继承路径的任何父模板或子模板。</p>
<p>例如，如果模板 <code class="docutils literal notranslate"><span class="pre">foo.html</span></code> 有 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">humanize</span> <span class="pre">%}</span></code>，那么子模板（例如，有 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">&quot;foo.html&quot;</span> <span class="pre">%}</span></code> 的子模板）将 <em>不能</em> 访问人性化模板标签和过滤器。子模板负责自己的 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">humanize</span> <span class="pre">%}</span></code>。</p>
<p>这是因为这能使模板更健全且更好维护。</p>
<div class="admonition seealso">
<p class="first admonition-title">参见</p>
<dl class="last docutils">
<dt><a class="reference internal" href="index.html"><span class="doc">模板参考</span></a></dt>
<dd>包括内置标签、内置过滤器、使用替代模板语言等。</dd>
</dl>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Django 模板语言</a><ul>
<li><a class="reference internal" href="#templates">模板</a></li>
<li><a class="reference internal" href="#variables">变量</a></li>
<li><a class="reference internal" href="#filters">过滤器</a></li>
<li><a class="reference internal" href="#tags">标签</a></li>
<li><a class="reference internal" href="#comments">注释</a></li>
<li><a class="reference internal" href="#template-inheritance">模板继承</a></li>
<li><a class="reference internal" href="#automatic-html-escaping">自动 HTML 转义</a><ul>
<li><a class="reference internal" href="#how-to-turn-it-off">如何关闭它</a><ul>
<li><a class="reference internal" href="#for-individual-variables">对于单个变量</a></li>
<li><a class="reference internal" href="#for-template-blocks">对于模板块</a></li>
</ul>
</li>
<li><a class="reference internal" href="#notes">注意</a></li>
<li><a class="reference internal" href="#string-literals-and-automatic-escaping">字符串和自动转义</a></li>
</ul>
</li>
<li><a class="reference internal" href="#accessing-method-calls">访问方法调用</a></li>
<li><a class="reference internal" href="#custom-tag-and-filter-libraries">自定义标签和过滤器库</a><ul>
<li><a class="reference internal" href="#custom-libraries-and-template-inheritance">自定义库和模板继承</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="index.html"
                        title="上一章">模板</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="builtins.html"
                        title="下一章">内置模板标签和过滤器</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/ref/templates/language.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">7月 23, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="index.html" title="模板">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="builtins.html" title="内置模板标签和过滤器">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>